package com.dapengjiaoyu.polyv_video_plugin;

import android.net.Uri;
import android.opengl.Visibility;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.RelativeLayout;

import com.easefun.polyvsdk.PolyvBitRate;
import com.easefun.polyvsdk.video.PolyvSeekType;
import com.easefun.polyvsdk.video.PolyvVideoView;
import com.easefun.polyvsdk.video.listener.IPolyvOnBufferingUpdateListener2;
import com.easefun.polyvsdk.video.listener.IPolyvOnCompletionListener2;
import com.easefun.polyvsdk.video.listener.IPolyvOnGestureClickListener;
import com.easefun.polyvsdk.video.listener.IPolyvOnGestureDoubleClickListener;
import com.easefun.polyvsdk.video.listener.IPolyvOnGestureLeftDownListener;
import com.easefun.polyvsdk.video.listener.IPolyvOnGestureLeftUpListener;
import com.easefun.polyvsdk.video.listener.IPolyvOnGestureRightDownListener;
import com.easefun.polyvsdk.video.listener.IPolyvOnGestureRightUpListener;
import com.easefun.polyvsdk.video.listener.IPolyvOnGestureSwipeLeftListener;
import com.easefun.polyvsdk.video.listener.IPolyvOnGestureSwipeRightListener;
import com.easefun.polyvsdk.video.listener.IPolyvOnGetCurrentPositionListener;
import com.easefun.polyvsdk.video.listener.IPolyvOnInfoListener2;
import com.easefun.polyvsdk.video.listener.IPolyvOnPlayPauseListener;
import com.easefun.polyvsdk.video.listener.IPolyvOnPreparedListener2;
import com.easefun.polyvsdk.video.listener.IPolyvOnVideoPlayErrorListener2;
import com.easefun.polyvsdk.video.listener.IPolyvOnVideoSizeChangedListener2;

import java.util.HashMap;
import java.util.Map;

import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.platform.PlatformView;

public class VideoView implements PlatformView, MethodChannel.MethodCallHandler {
    private RelativeLayout layout;
    private PolyvVideoView videoView;
    private final MethodChannel methodChannel;
    private final PluginRegistry.Registrar registrar;


    VideoView(int viewId, Object args, PluginRegistry.Registrar registrar) {
        this.registrar = registrar;
        this.layout = getPolyvVideoView(registrar, args);
        this.methodChannel = new MethodChannel(registrar.messenger(), "polyv_video_plugin_" + viewId);
        this.methodChannel.setMethodCallHandler(this);
    }

    @Override
    public View getView() {
        return layout;
    }


    @Override
    public void dispose() {
        videoView.destroy();
    }

    private RelativeLayout getPolyvVideoView(PluginRegistry.Registrar registrar, Object args) {
        layout = (RelativeLayout) LayoutInflater.from(registrar.activity()).inflate(R.layout.polyv_video, null);
//        layout.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        videoView = layout.findViewById(R.id.polyv_video_view);
        videoView.setNeedGestureDetector(true);
        videoView.setOpenPreload(true);
        videoView.setAutoContinue(true);
        videoView.setSeekType(PolyvSeekType.SEEKTYPE_ACCURATE);
        videoView.setNeedGestureDetector(true);
        videoView.setOnGestureClickListener(new IPolyvOnGestureClickListener() {
            @Override
            public void callback(boolean start, boolean end) {
                Map<String, String> map = new HashMap<>();
                map.put("type", "click");
                methodChannel.invokeMethod("listener", map);
            }
        });
        videoView.setOnGestureDoubleClickListener(new IPolyvOnGestureDoubleClickListener() {
            @Override
            public void callback() {
                Map<String, String> map = new HashMap<>();
                map.put("type", "doubleClick");
                methodChannel.invokeMethod("listener", map);
            }
        });
        videoView.setOnGestureLeftDownListener(new IPolyvOnGestureLeftDownListener() {
            @Override
            public void callback(boolean start, boolean end) {
                Map<String, Object> map = new HashMap<>();
                map.put("type", "leftDown");
                map.put("start", start);
                map.put("end", end);
                methodChannel.invokeMethod("listener", map);
            }
        });

        videoView.setOnGestureLeftUpListener(new IPolyvOnGestureLeftUpListener() {
            @Override
            public void callback(boolean b, boolean b1) {
                Map<String, Object> map = new HashMap<>();
                map.put("type", "leftUp");
                map.put("start", b);
                map.put("end", b1);
                methodChannel.invokeMethod("listener", map);
            }
        });

        videoView.setOnGestureRightDownListener(new IPolyvOnGestureRightDownListener() {
            @Override
            public void callback(boolean b, boolean b1) {
                Map<String, Object> map = new HashMap<>();
                map.put("type", "rightDown");
                map.put("start", b);
                map.put("end", b1);
                methodChannel.invokeMethod("listener", map);
            }
        });

        videoView.setOnGestureRightUpListener(new IPolyvOnGestureRightUpListener() {
            @Override
            public void callback(boolean b, boolean b1) {
                Map<String, Object> map = new HashMap<>();
                map.put("type", "rightUp");
                map.put("start", b);
                map.put("end", b1);
                methodChannel.invokeMethod("listener", map);
            }
        });

        videoView.setOnGestureSwipeLeftListener(new IPolyvOnGestureSwipeLeftListener() {
            @Override
            public void callback(boolean b, boolean b1) {
                Map<String, Object> map = new HashMap<>();
                map.put("type", "swipeLeft");
                map.put("start", b);
                map.put("end", b1);
                methodChannel.invokeMethod("listener", map);
            }
        });

        videoView.setOnGestureSwipeRightListener(new IPolyvOnGestureSwipeRightListener() {
            @Override
            public void callback(boolean b, boolean b1) {
                Map<String, Object> map = new HashMap<>();
                map.put("type", "swipeRight");
                map.put("start", b);
                map.put("end", b1);
                methodChannel.invokeMethod("listener", map);
            }
        });
        videoView.setOnPreparedListener(new IPolyvOnPreparedListener2() {
            @Override
            public void onPrepared() {
                Map<String, String> map = new HashMap<>();
                map.put("type", "onPrepared");
                methodChannel.invokeMethod("listener", map);
            }
        });
        videoView.startGetCurrentPositionTask();
        videoView.setOnGetCurrentPositionListener(new IPolyvOnGetCurrentPositionListener() {
            @Override
            public void onGet(String vid, int currentPositionMs) {
                Map<String, String> map = new HashMap<>();
                map.put("type", "onCurrentPosition");
                map.put("vid", vid);
                map.put("currentPositionMs", String.valueOf(currentPositionMs));
                methodChannel.invokeMethod("listener", map);
            }
        });

        videoView.setOnBufferingUpdateListener(new IPolyvOnBufferingUpdateListener2() {
            @Override
            public void onBufferingUpdate(int percent) {
                Map<String, String> map = new HashMap<>();
                map.put("type", "onBufferingUpdate");
                map.put("percent", String.valueOf(percent));
                methodChannel.invokeMethod("listener", map);
            }
        });

        videoView.setOnPlayPauseListener(new IPolyvOnPlayPauseListener() {
            @Override
            public void onPause() {
                Map<String, String> map = new HashMap<>();
                map.put("type", "onPause");
                methodChannel.invokeMethod("listener", map);
            }

            @Override
            public void onPlay() {
                Map<String, String> map = new HashMap<>();
                map.put("type", "onPlay");
                methodChannel.invokeMethod("listener", map);
            }

            @Override
            public void onCompletion() {
                Map<String, String> map = new HashMap<>();
                map.put("type", "onCompletion");
                methodChannel.invokeMethod("listener", map);
            }
        });
        videoView.setOnVideoPlayErrorListener(new IPolyvOnVideoPlayErrorListener2() {
            @Override
            public boolean onVideoPlayError(int errorReason) {
                Map<String, String> map = new HashMap<>();
                map.put("type", "onVideoPlayError");
                map.put("msg", String.valueOf(errorReason));
                methodChannel.invokeMethod("listener", map);
                return false;
            }
        });

        videoView.setOnInfoListener(new IPolyvOnInfoListener2() {
            @Override
            public boolean onInfo(int what, int extra) {
                Map<String, String> map = new HashMap<>();
                map.put("type", "onInfo");
                map.put("msg", String.valueOf(what));
                methodChannel.invokeMethod("listener", map);
                return true;
            }
        });

        videoView.setOnCompletionListener(new IPolyvOnCompletionListener2() {
            @Override
            public void onCompletion() {
                Map<String, String> map = new HashMap<>();
                map.put("type", "onCompletion");
                methodChannel.invokeMethod("listener", map);
            }
        });

        videoView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
            @Override
            public void onSystemUiVisibilityChange(int visibility) {
                System.out.println(visibility);
            }
        });

        videoView.setOnVideoSizeChangedListener(new IPolyvOnVideoSizeChangedListener2() {
            @Override
            public void onVideoSizeChanged(int width, int height, int sarNum, int sarDen) {
                Map<String, String> map = new HashMap<>();
                map.put("type", "onVideoSizeChanged");
                methodChannel.invokeMethod("listener", map);
            }
        });
        return layout;
    }

    @Override
    public void onMethodCall(MethodCall methodCall, final MethodChannel.Result result) {
        Map<String, String> arg = (Map<String, String>) methodCall.arguments;
        switch (methodCall.method) {
            case "setVideoURI":
                String url = arg.get("url");
                videoView.setVideoURI(Uri.parse(url));
                break;
            case "setVid":
                videoView.setVid(arg.get("vid"));
                break;
            case "stop":
                videoView.stopPlayback();
                break;
            case "start":
                videoView.start();
                break;
            case "resume":
                videoView.resume();
                break;
            case "pause":
                videoView.pause();
                break;
            case "isPlaying":
                result.success(videoView.isPlaying());
                break;
            case "destroy":
                videoView.destroy();
                break;
            case "duration":
                result.success(videoView.getDuration());
                break;
            case "currentPosition":
                result.success(videoView.getCurrentPosition());
                break;
            case "bufferPercentage":
                result.success(videoView.getBufferPercentage());
                break;
            case "brightness":
                result.success(videoView.getBrightness(registrar.activity()));
                break;
            case "setBrightness":
                videoView.setBrightness(registrar.activity(), Integer.parseInt(arg.get("brightness")));
                break;
            case "setVolume":
                videoView.setVolume(Integer.parseInt(arg.get("volume")));
                break;
            case "volume":
                result.success(videoView.getVolume());
                break;
            case "seekTo":
                videoView.seekTo(Long.parseLong(arg.get("progress")));
                break;
            case "setPlayRate":
                videoView.setSpeed(Float.parseFloat(arg.get("rate")));
                break;
            case "setQuality":
                videoView.changeBitRate(Integer.parseInt(arg.get("quality").substring(0,1)));
                break;
            default:
                result.notImplemented();
        }
    }
}